/**
 * Copyright (c) 2019 Coder League
 * All rights reserved.
 *
 * File：MerchantSettlementsMgrService.java
 * History:
 *         2019年6月15日: Initially created, wangjb.
 */
package club.coderleague.ilsp.service.merchantsettlements;

import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

import org.apache.poi.ss.usermodel.CellStyle;
import org.apache.poi.ss.usermodel.HorizontalAlignment;
import org.apache.poi.ss.usermodel.VerticalAlignment;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import club.coderleague.data.jpa.domain.Page;
import club.coderleague.ilsp.common.domain.beans.ExportMerchantSettlementExtension;
import club.coderleague.ilsp.common.domain.beans.MerchantSettlementsExtension;
import club.coderleague.ilsp.common.domain.enums.CapitalChangedReason;
import club.coderleague.ilsp.common.domain.enums.EntityState;
import club.coderleague.ilsp.common.domain.enums.NotifyType;
import club.coderleague.ilsp.common.domain.enums.PaymentTypeEnums;
import club.coderleague.ilsp.common.domain.enums.SettlementTypeEnums;
import club.coderleague.ilsp.dao.MerchantSettlementsDao;
import club.coderleague.ilsp.dao.MerchantsDao;
import club.coderleague.ilsp.entities.Merchants;
import club.coderleague.ilsp.entities.Merchantsettlements;
import club.coderleague.ilsp.service.interfaces.AliyunInterfaceService;

/**
 * 商户结算管理业务处理。
 * @author wangjb
 */
@Service
public class MerchantSettlementsMgrService {
	
	/**
	 * 商户结算数据访问对象。
	 */
	@Autowired MerchantSettlementsDao settlementsDao;
	
	/**
	 * 商户数据访问对象。
	 */
	@Autowired MerchantsDao merchantsDao;
	
	/**
	 * 资金记录接口。
	 */
	@Autowired club.coderleague.ilsp.service.capitalrecords.CapitalRecordsService capitalRecordsService;
	
	/**
	 * 短信提醒服务。
	 */
	@Autowired AliyunInterfaceService aliyunInterfaceService;
	
	/**
	 * 获取商户结算分页数据。
	 * @author wangjb 2019年6月15日。
	 * @param params 页面查询查询。
	 * @return
	 */
	public Page<MerchantSettlementsExtension> getMerchantSettlementsMgrService(Map<String, Object> params) throws Exception {
		Page<MerchantSettlementsExtension> result = this.settlementsDao.getMerchantSettlementsMgrDao(params);
		return result;
	}

	/**
	 * 获取自动结算的商户数据。
	 * @author wangjb 2019年6月15日。
	 * @param params 页面查询参数。
	 * @return
	 * @throws Exception
	 */
	public Page<Merchants> getMerchanstListService(Map<String, Object> params) throws Exception {
		Page<Merchants> result = this.merchantsDao.getMerchanstListDao(params);
		return result;
	}

	/**
	 * 自动结算。
	 * @author wangjb 2019年6月15日。
	 * @param result 返回操作提示。
	 * @param ids 商户id。
	 * @param userid 操作人员id。
	 * @throws Exception 业务处理异常。
	 */
	public XSSFWorkbook executeSaveMerchantSettlementService(String ids, Long userid) throws Exception {
		List<Long> idList = new ArrayList<Long>();
		if (ids != null && !"".equals(ids)) {
			for (String id : ids.split(",")) {
				Long merchantid = Long.valueOf(id);
				Merchants merchants = this.merchantsDao.getOne(merchantid);
				BigDecimal totalamount = new BigDecimal(Double.toString(merchants.getTotalamount()));  
	            BigDecimal lockedamount = new BigDecimal(Double.toString(merchants.getLockedamount())); 
				if (totalamount.subtract(lockedamount).doubleValue() == 0)  continue; // 账户总额-锁定金额等于 跳出。
				Merchantsettlements settlement = new Merchantsettlements();
				settlement.setHandler(userid);
				settlement.setEntitystate(EntityState.PAYMENT.getValue()); // 处理中。
				settlement.setMerchantid(merchantid);
				settlement.setSettlementtype(SettlementTypeEnums.AUTOMATIC.getValue()); // 自动结算。
				settlement.setPaymenttype(PaymentTypeEnums.ARTIFICIAL.getValue()); // 人工打款。
				settlement.setApplytime(new Date());
				settlement.setSettlementamount(merchants.getTotalamount()); // 结算金额。
				this.settlementsDao.save(settlement);
				
				// 锁定金额。
				this.capitalRecordsService.updateLockCapitalByMerchantid(merchantid, merchants.getTotalamount());
				idList.add(merchantid);
			}
		}
		// 导出表格。
		XSSFWorkbook workbook = this.exportMerchantsMessageService(idList);
		return workbook;
	}

	/**
	 * 手动结算。
	 * @author wangjb 2019年6月15日。
	 * @param ids 待付款id。
	 * @param userid 操作人员id。
	 * @param result 返回操作提示。
	 */
	public XSSFWorkbook executeManualSettleByIdsService(String ids, Long userid) {
		List<Long> idList = new ArrayList<Long>();
		if (ids != null && !"".equals(ids)) {
			for (String id : ids.split(",")) {
				Merchantsettlements settlement = this.settlementsDao.getOne(Long.valueOf(id));
				settlement.setEntitystate(EntityState.PAYMENT.getValue());
				idList.add(settlement.getMerchantid());
			}
		}
		// 导出表格。
		XSSFWorkbook workbook = this.exportMerchantsMessageService(idList);
		return workbook;
	}
	
	/**
	 * 导出商户信息。
	 * @author wangjb 2019年7月29日。
	 * @param ids
	 * @return
	 */
	public XSSFWorkbook executeExportExcelByIdsService(String ids) {
		List<Long> idList = new ArrayList<Long>();
		if (ids != null && !"".equals(ids)) {
			for (String id : ids.split(",")) {
				Merchantsettlements settlement = this.settlementsDao.getOne(Long.valueOf(id));
				idList.add(settlement.getMerchantid());
			}
		}
		// 导出表格。
		XSSFWorkbook workbook = this.exportMerchantsMessageService(idList);
		return workbook;
	}
	
	/**
	 * 导出excel商户信息。
	 * @author wangjb 2019年7月26日。
	 * @param midList 商户id。
	 * @return
	 */
	private XSSFWorkbook exportMerchantsMessageService(List<Long> midList) {
		XSSFWorkbook workbook = new XSSFWorkbook();
		String date = new SimpleDateFormat("yyyy-MM-dd").format(new Date());
		XSSFSheet sheet = workbook.createSheet(date + "_商户结算表");
		// 表头标题
		XSSFRow oneheadrow = sheet.createRow(0);
        oneheadrow.createCell(0).setCellValue("序号");
        oneheadrow.createCell(1).setCellValue("商户名称");
        oneheadrow.createCell(2).setCellValue("商户电话");
        oneheadrow.createCell(3).setCellValue("身份证号");
        oneheadrow.createCell(4).setCellValue("账户名称");
        oneheadrow.createCell(5).setCellValue("银行卡号");
        oneheadrow.createCell(6).setCellValue("开户银行");
        oneheadrow.createCell(7).setCellValue("开户网点");
        oneheadrow.createCell(8).setCellValue("结算金额");
        // 表头样式
        CellStyle headstyle = workbook.createCellStyle();
        headstyle.setAlignment(HorizontalAlignment.CENTER);
        headstyle.setVerticalAlignment(VerticalAlignment.CENTER);
        oneheadrow.getCell(0).setCellStyle(headstyle);
        oneheadrow.getCell(1).setCellStyle(headstyle);
        oneheadrow.getCell(2).setCellStyle(headstyle);
        oneheadrow.getCell(3).setCellStyle(headstyle);
        oneheadrow.getCell(4).setCellStyle(headstyle);
        oneheadrow.getCell(5).setCellStyle(headstyle);
        oneheadrow.getCell(6).setCellStyle(headstyle);
        oneheadrow.getCell(7).setCellStyle(headstyle);
        oneheadrow.getCell(8).setCellStyle(headstyle);
        
        List<ExportMerchantSettlementExtension> exportlist = this.settlementsDao.getExportMerchantSettlementExtensionByMidDao(midList);
        if (exportlist != null && !exportlist.isEmpty()) {
        	int rownum = 1;
        	for (ExportMerchantSettlementExtension  merchant : exportlist) {
        		XSSFRow row = sheet.createRow(rownum);
        		row.createCell(0).setCellValue(rownum);
        		row.createCell(1).setCellValue(merchant.getMerchantname());
        		row.createCell(2).setCellValue(merchant.getMerchantphone());
        		row.createCell(3).setCellValue(merchant.getIdnumber());
        		row.createCell(4).setCellValue(merchant.getAccountname());
        		row.createCell(5).setCellValue(merchant.getBcnumber());
        		row.createCell(6).setCellValue(merchant.getBankname());
        		row.createCell(7).setCellValue(merchant.getBankcard());
        		row.createCell(8).setCellValue(merchant.getTotalamount());
        		rownum++;
        	}
        }
		return workbook;
	}
	
	/**
	 * 执行结算完成操作。
	 * @author wangjb 2019年7月27日。
	 * @param result 返回操作提示。
	 * @param entityid 结算id。
	 * @param payevidence 付款凭证。
	 * @param paytime 付款时间。
	 * @param userid 操作人员。
	 * @throws Exception 业务处理异常。
	 */
	public void executeSettleOverService(Map<String, Object> result, Long entityid, String payevidence, String paytime,
			Long userid) throws Exception {
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
		Date pt = sdf.parse(paytime);
		Merchantsettlements settlement = this.settlementsDao.getOne(entityid);
		settlement.setEntitystate(EntityState.SETTLEOVER.getValue());
		settlement.setHandler(userid);
		settlement.setPaymenttype(PaymentTypeEnums.ARTIFICIAL.getValue()); // 人工打款。
		settlement.setPaytime(pt);
		settlement.setPayevidence(payevidence);
		// 使用金额。
		this.capitalRecordsService.updateUseCapitalByMerchantid(settlement.getMerchantid(), settlement.getSettlementamount(), CapitalChangedReason.SETTLE_ACCOUNTS, "后台自动结算");
		// 通知商户。
		this.aliyunInterfaceService.sendAccountRemind(NotifyType.SETACC_REMIND, settlement.getMerchantid(), settlement.getSettlementamount()); 
		result.put("state", true);
		result.put("msg", "操作成功!");
	}

	/**
	 * 执行结算取消操作。
	 * @author wangjb 2019年7月27日。
	 * @param result 返回操作提示。
	 * @param ids 结算id。
	 * @param cancelreason 取消原因
	 * @param paytime 取消时间。
	 * @param userid 操作人员id。
	 * @throws Exception 
	 */
	public void executeSettleCancelService(Map<String, Object> result, String ids, String cancelreason,
			String paytime, Long userid) throws Exception {
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
		Date pt = sdf.parse(paytime);
		if (ids != null && !"".equals(ids)) {
			for (String id : ids.split(",")) {
				Long settleid = Long.valueOf(id);
				Merchantsettlements settlement = this.settlementsDao.getOne(settleid);
				settlement.setEntitystate(EntityState.SETTLECANCEL.getValue());
				settlement.setPaytime(pt);
				settlement.setCancelreason(cancelreason);
				settlement.setPaymenttype(PaymentTypeEnums.ARTIFICIAL.getValue()); // 人工打款。
				settlement.setHandler(userid);
				
				// 解锁金额。
				this.capitalRecordsService.updateUnlockCapitalByMerchantid(settlement.getMerchantid(), settlement.getSettlementamount());
			}
		}
		result.put("state", true);
		result.put("msg", "操作成功!");
	}
}
